//
// Manta - Structural Variant and Indel Caller
// Copyright (c) 2013-2019 Illumina, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//

/// \file
/// \author Chris Saunders
///
/// an efficient (and slightly unsafe) class for basic tab-delimited files, etc...
///

#pragma once

#include <iosfwd>

struct istream_line_splitter {
  istream_line_splitter(
      std::istream&  is,
      const unsigned line_buf_size  = 8 * 1024,
      const char     word_seperator = '\t',
      const unsigned max_word       = 0)
    : _is(is),
      _line_no(0),
      _n_word(0),
      _buf_size(line_buf_size),
      _sep(word_seperator),
      _max_word(max_word),
      _buf(new char[_buf_size])
  {
    if ((0 == _max_word) || (MAX_WORD_COUNT < _max_word)) {
      _max_word = MAX_WORD_COUNT;
    }
  }

  ~istream_line_splitter()
  {
    if (nullptr != _buf) {
      delete[] _buf;
      _buf = nullptr;
    }
  }

  unsigned n_word() const { return _n_word; }

  /// returns false for regular end of input:
  bool parse_line();

  // recreates the line before parsing
  void write_line(std::ostream& os) const;

  // debug output, which provides line number and other info before calling write_line
  void dump(std::ostream& os) const;

  enum { MAX_WORD_COUNT = 50 };
  char* word[MAX_WORD_COUNT];

private:
  void increase_buffer_size();

  std::istream& _is;
  unsigned      _line_no;
  unsigned      _n_word;
  unsigned      _buf_size;
  char          _sep;
  unsigned      _max_word;
  char*         _buf;
};

#if 0
{
    //usage example:
    istream_line_splitter dparse(data_is);

    while (dparse.parse_line())
    {
        static const unsigned col_count(46);
        if (dparse.n_word()!=col_count)
        {
            std::ostringstream oss;
            oss << "Unexpected number of columns in paired export line:\n\n";
            dparse.dump(oss);
            throw blt_exception(oss.str().c_str());
        }

        for (unsigned i(1); (i+1)<col_count; ++i)
        {
            dparse.word[i][strlen(dparse.word[i])] = sep;
        }
        const char* nocompress_segment(dparse.word[0]);
        const char* compress_segment(dparse.word[1]);

        /// ....etc
    }
}
#endif
